#include <iostream>
#include <vector>
#include <type_traits>
#include <memory>
#include <string>
#include <iterator>
using namespace std;

template <class Iterator>
struct my_iterator_traits {
  // 迭代器种类
  typedef typename Iterator::iterator_category iterator_category;
  // 表示迭代器所指向对象的类型
  typedef typename Iterator::value_type        value_type;
  // 表示迭代器之间的距离, 切记指针之间不能相加，但是能相减
  typedef typename Iterator::difference_type   difference_type;
  // 指针
  typedef typename Iterator::pointer           pointer;
  // 引用
  typedef typename Iterator::reference         reference;
};

// 偏特化
template <class T>
struct my_iterator_traits<T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef T*                         pointer;
  typedef T&                         reference;
};

// 偏特化
template <class T>
struct my_iterator_traits<const T*> {
  typedef random_access_iterator_tag iterator_category;
  typedef T                          value_type;
  typedef ptrdiff_t                  difference_type;
  typedef const T*                   pointer;
  typedef const T&                   reference;
};

//定义两种无参结构体是为了函数重载准备
struct my__true_type {

};

struct my__false_type {
    
};

template <class type>
struct my__type_traits {
    typedef my__true_type this_dummy_member_must_be_first;//用于占位，确保某些编译器的行为
    typedef my__false_type    has_trivial_default_constructor;//默认构造函数是否为平凡
    typedef my__false_type    has_trivial_copy_constructor;//拷贝构造函数是否平凡
    typedef my__false_type    has_trivial_assignment_operator;//赋值运算符是否平凡
    typedef my__false_type    has_trivial_destructor;//析构函数是否平凡
    typedef my__false_type    is_POD_type;//是否是POD类型
};

template <>
struct my__type_traits<char> {
   typedef my__true_type    has_trivial_default_constructor;
   typedef my__true_type    has_trivial_copy_constructor;
   typedef my__true_type    has_trivial_assignment_operator;
   typedef my__true_type    has_trivial_destructor;
   typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<signed char> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
 struct my__type_traits<unsigned char> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<int> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<unsigned int> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <class T>
struct my__type_traits<T*> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<char*> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<signed char*> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <>
struct my__type_traits<unsigned char*> {
    typedef my__true_type    has_trivial_default_constructor;
    typedef my__true_type    has_trivial_copy_constructor;
    typedef my__true_type    has_trivial_assignment_operator;
    typedef my__true_type    has_trivial_destructor;
    typedef my__true_type    is_POD_type;
};

template <class ForwardIterator, class Size, class T>
inline ForwardIterator my__uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, my__true_type)
{
    //此段代码用于在未初始化的内存中填充值，用于基础类型
    return fill_n(first, n, x);
}

template <class ForwardIterator, class Size, class T>
ForwardIterator my__uninitialized_fill_n_aux(ForwardIterator first, Size n, const T& x, my__false_type) 
{
    //此段代码用于在未初始化的内存范围内填充值，适用于非POD类型（由__false_type标识）
    //false_type表示T是非POD类型
    ForwardIterator cur = first;//创建一个迭代器cur，指向范围的起始位置
    try {
        for(; n > 0; --n, ++cur)
            construct(&*cur, x);
            //在cur位置构建一个对象，值为x
        return cur;
    }
    catch(...) {
        destroy(first, cur);
        throw;
    }
}

//这里我们对于这个内部函数做一个我们自己方法的实现（自己对于源码的一个理解）
//根据类型是否为POD选择不同的实现
template <class ForwardIterator, class Size, class T, class T1>//T1* 一个指向类型T1的指针，用于推断迭代器First所指向元素的类型
inline ForwardIterator my__uninitialized_fill_n(ForwardIterator first,
                                              Size n, 
                                              const T& x, T1*)
{
    //这个函数作用为根据类型是否为POD来选择不同的实现方式
    //type_traits一个类型的萃取工具，用于判断类型T1是否为POD类型
    //POD类型是指简单的，可以被直接复制和初始化的类型（基本类型， 结构体等）
    typedef typename my__type_traits<T1>::is_POD_type is_POD;
    return my__uninitialized_fill_n_aux(first, n, x, is_POD());
}


//这个函数用来构建一个大小为N个value的空间，并根据T类型确定是普通赋值还是拷贝构造
template <class ForwardIterator, class Size, class T>//first一个指向未初始化内存范围的起始位置的迭代器
inline ForwardIterator my_uninitialized_fill_n(ForwardIterator first, Size n, const T& x)
{
    //内部辅助函数，负责实际填充未初始化的内存
    typedef typename iterator_traits<ForwardIterator>::value_type value_type;
    return my__uninitialized_fill_n(first, n, x, static_cast<value_type*>(nullptr));
}


int main()
{
    //测试POD类型(int)
    {
        int* p = new int[5];
        my_uninitialized_fill_n(p, 5, 42);
        cout << "POD类型(int)测试：" ;
        for(int i = 0; i < 5; i++) {
            cout << p[i] << " " ;
        }
        cout << endl;
        delete [] p;
    }

    //测试POD类型(char)
    {
        char* p = new char[5];
        my_uninitialized_fill_n(p, 5, 'A');
        cout << "POD 类型 (char) 测试: ";
        for (int i = 0; i < 5; ++i) {
            cout << p[i] << " ";
        }
        cout << endl;
        delete[] p;
    }

    //测试非POD类型(string) 
    // {
    //     allocator <string> alloc;
    //     string *p = alloc.allocate(5);
    //     my_uninitialized_fill_n(p, 5, 'hello');
    //     cout << "非POD类型(string)测试：";
    //     for(int i = 0; i < 5; i++) {
    //         cout << p[i] << " ";
    //     } 
    //     cout << endl;
    //     for(int i = 0; i < 5; i++) {
    //         alloc.destroy(&p[i]);
    //     }
    //     alloc.deallocate(p, 5);
    // }
    return 0;
}